#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

// 不定参宏函数使用
#define LOG1(fmt, ...) printf("[%s:%d]: " fmt, __FILE__, __LINE__, __VA_ARGS__)
#define LOG2(fmt, ...) printf("[%s:%d]: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)

// C语言，不定参函数使用
void printNum(int count, ...)
{
    // 1.定义 va_list 类型变量
    va_list lo_ap;
    // 2.获取起始变量->count之后的第一个参数
    va_start(lo_ap, count);
    for (int i = 0; i < count; i++)
    {
        // 3.获得参数及类型，ap会自动偏移
        int num = va_arg(lo_ap, int);
        printf("param[%d]:%d\n", i, num);
    }
    // 将ap指针置空
    va_end(lo_ap);
}

// 基于linux的扩展
void myprintf(const char *format, ...)
{
    // 1.定义 va_list 类型变量
    va_list args;
    // 2.获取起始变量->count之后的第一个参数
    va_start(args, format);
    char *buf;
    int ret = vasprintf(&buf, format, args);
    // 3.获得参数及类型，ap会自动偏移
    if (ret != -1)
    {
        printf(buf);
        free(buf);
    }
    // 将ap指针置空
    va_end(args);
}

//基于C++的不定参函数使用
//特化--支持无参数->递归调用最后是无参函数
void cppmyprintf()
{
	std::cout << std::endl;
}
//函数主体
template<class T, class ...Args>
//const T& value ->const不能省略
void cppmyprintf(const T& value, Args &&...args)
{
	std::cout << value << " ";
	//sizeof ...(args)->sizeof扩展：可以计算剩余参数个数
	//(args)->()不能省略
	if ((sizeof ...(args)) > 0)
	{
		//std::forward<Args>(args)... ->forward：完美转发，避免右值或引用退化
		//(args)->()不能省略
		cppmyprintf(std::forward<Args>(args)...);
	}
	else
	{
		cppmyprintf();
	}
}


int main()
{

    LOG1("%s\n", "ok");
    LOG2("ok\n");

    printNum(3, 22, 33, 44);
    printNum(7, 71, 72, 73, 74, 75, 76, 77);
    int a = 5;
    myprintf("[%s:%d]: %s %d %c %p\n", __FILE__, __LINE__, "ok", 6, '&', &a);
	std::cout << "*************" << std::endl;

	cppmyprintf(71, 72, 73, 74, 75, 76, 77);
    return 0;
}